parseJSONCol <- function(col) {
#converts ' to " except when surrounded by alphabetical letters, like "you've"
col <- str_replace_all(col, "(?<![a-zA-Z])'(.*?)'(?![a-zA-Z])", "\"\\1\"")
col <- lapply(col, fromJSON)
return(col)
}
# Apply the transformation to all columns with stringified JSON
tutorial <- tutorial_raw %>%
mutate(across(4:9, parseJSONCol)) %>%
pivot_longer(cols = 4:9, names_to = "qlabel") %>%
unnest_wider(value)
endParse <- function(col) {
col <- lapply(col, function(c) {strsplit(c, "'a': ")[[1]][2]})
col <- str_remove_all(col, "\\}")
return(col)
}
end <- end_raw %>%
mutate(across(4:6, endParse)) #%>%
# View()
demo <- demo_raw %>%
mutate(across(4:10, endParse))
# Distribution of responses to tutorial questions
tutorial %>%
mutate(correctans = a == corr) %>%
ggplot(aes(x=a, fill=correctans)) +
geom_bar(stat="count") +
scale_x_discrete("participant response") +
scale_fill_manual(values=c("red","forestgreen")) +
facet_wrap(~q, scales="free_x", nrow=3) +
theme_bw() +
theme(strip.text.x = element_text(size = 8))
ggsave("fig/tut_distqs.png", width=9, height=6)
# Distribution of correct responses for participants
passtutorial <- tutorial %>%
mutate(correctans = a == corr) %>%
group_by(subjID) %>%
summarise(tutcorr = sum(correctans))
passtutorial %>%
ggplot(aes(x=tutcorr)) +
geom_bar(stat="count") +
scale_x_continuous("participant total correct responses") +
scale_y_continuous(limits=c(0,20)) +
theme_bw()
ggsave("fig/tut_distcorr.png", width=6, height=4)
raw %>%
filter(exptPart == "tutorial") %>%
count(subjID, numTrial) %>%
ggplot(aes(x=n)) +
geom_bar(stat="count") +
facet_wrap(~numTrial)
completedTut <- raw %>%
filter(exptPart == "tutorial") %>%
count(subjID, numTrial) %>%
complete(subjID, numTrial, fill=list(n=0))
completedTut %>%
arrange(n, desc(numTrial))
## # A tibble: 102 × 3
## subjID numTrial n
## <chr> <dbl> <int>
## 1 connect-01BDCB71123048979A77AB656EEBD585 2 0
## 2 connect-4DB4741723D94FD2B85BB902808C0730 2 0
## 3 connect-A0D00061575B499A8080DBF3CACA6A08 2 0
## 4 connect-B19D08B7E13D4CBFB503C08C6E51FF96 2 0
## 5 connect-FA3BED3C33C047EAB2768EF5172A1310 2 0
## 6 connect-4DB4741723D94FD2B85BB902808C0730 1 0
## 7 connect-A0D00061575B499A8080DBF3CACA6A08 1 0
## 8 connect-B19D08B7E13D4CBFB503C08C6E51FF96 1 0
## 9 connect-FA3BED3C33C047EAB2768EF5172A1310 1 0
## 10 connect-0F07CDB90B904FB79C385106E46337DE 2 1
## # ℹ 92 more rows
# get participants who didn't finish tutorial
didntfinish <- completedTut %>%
filter(n == 0) %>%
distinct(subjID) %>%
pull(subjID)
didntfinish
## [1] "connect-01BDCB71123048979A77AB656EEBD585"
## [2] "connect-4DB4741723D94FD2B85BB902808C0730"
## [3] "connect-A0D00061575B499A8080DBF3CACA6A08"
## [4] "connect-B19D08B7E13D4CBFB503C08C6E51FF96"
## [5] "connect-FA3BED3C33C047EAB2768EF5172A1310"
strokes %>%
filter(exptPart == "tutorial" & !subjID %in% didntfinish) %>%
mutate(editaction = ifelse(action %in% c("clear","undo"), "remove", action),
editaction = ifelse(editaction == "drawerror", "error", editaction),
numtrial = as.factor(numtrial),
subjID = substring(subjID, 9, 18)) %>%
ggplot(aes(x = editaction, fill = numtrial)) +
geom_bar(stat="count", position="stack") +
facet_wrap(~subjID, nrow=5) +
theme_bw()
ggsave("fig/tutorialstrokes.png", width=10, height=8)
# some participants are missing strokes in tutorial trial 1 -- look up who these are
strokes %>%
filter(exptPart == "tutorial" & !subjID %in% didntfinish) %>%
mutate(editaction = ifelse(action %in% c("clear","undo"), "remove", action),
numtrial = as.factor(numtrial)) %>%
count(subjID, numtrial) %>% #count number of actions per trial
complete(subjID, numtrial, fill=list(n=0)) %>%
filter(n == 0) %>%
pull(subjID)
## [1] "connect-450BA15B1E9D4B76BC0DCB0D9BF11DAB"
## [2] "connect-4ECCC073A845416680A6078E5A14A8F7"
## [3] "connect-B9360F5511954062A797B1228A4AF9E9"
techIssues <- c("connect-450BA15B1E9D4B76BC0DCB0D9BF11DAB")
#commented about technical challenges
failedSubj <- passtutorial %>%
filter(tutcorr < 4) %>%
pull(subjID)
data <- raw %>%
filter(!subjID %in% c(failedSubj, didntfinish, techIssues), exptPart == "test") %>%
mutate(subjID = substring(subjID, 9, 18))
strokedat <- strokes %>%
filter(!subjID %in% c(failedSubj, didntfinish, techIssues), exptPart == "test",
numattempt < 5) %>%
mutate(subjID = substring(subjID, 9, 18))
# number of participants
data %>%
distinct(subjID) %>%
nrow()
## [1] 27
# 27 participants -- 1 was removed for failing tutorial survey, 1 had data saving issues, 1 had line drawing issues
# did all participants do all 20 trials
data %>%
distinct(subjID, numTrial) %>%
filter(numTrial == 19)
## # A tibble: 27 × 2
## subjID numTrial
## <chr> <dbl>
## 1 1DF28D04D4 19
## 2 DF011FC195 19
## 3 BDE67C2DF7 19
## 4 A4CF186F80 19
## 5 3816DCE76C 19
## 6 4E48E94501 19
## 7 6F75D8B9C0 19
## 8 71AEE38C92 19
## 9 F9E998D1F7 19
## 10 AD5993CF4D 19
## # ℹ 17 more rows
# all 27 participants completed trials 0 to 19
imageInfo <- raw %>%
filter(!subjID %in% c(failedSubj, didntfinish, techIssues), exptPart == "test") %>%
mutate(success = ifelse(runOutcome == "goal", "success", "fail"),
tempattempt = 1) %>%
group_by(subjID) %>%
mutate(cumulativeAttempt = cumsum(tempattempt),
cumulativeAttempt = cumulativeAttempt - 1,
imageID = paste0(subjID, "_img", cumulativeAttempt, ".png"),
directory = paste0(subjID,"/",imageID)) %>%
select(subjID, levelID, gravX, gravY, radius, numAttempts, success, imageID, directory)
write.csv(imageInfo, "imagedf.csv")
## number of total attempts by participants
data %>%
count(subjID) %>%
arrange(n)
## # A tibble: 27 × 2
## subjID n
## <chr> <int>
## 1 A4CF186F80 34
## 2 0F07CDB90B 36
## 3 4E48E94501 36
## 4 4ECCC073A8 37
## 5 4C241572C4 41
## 6 F8D52DE7E5 41
## 7 7E0D9F23EB 43
## 8 C809D394C2 45
## 9 DF011FC195 45
## 10 71AEE38C92 46
## # ℹ 17 more rows
data %>%
count(subjID) %>%
ggplot(aes(x=n)) +
geom_histogram(binwidth=5)
## number of trials/conditions
data %>%
filter(numAttempts == 0) %>%
count(levelID, gravX, gravY, radius) %>%
complete(levelID, gravX, gravY, radius, fill=list(n=0)) %>%
arrange(n)
## # A tibble: 168 × 5
## levelID gravX gravY radius n
## <chr> <dbl> <dbl> <dbl> <int>
## 1 basic_far 0 2.5 30 0
## 2 basic_short -0.25 1 30 0
## 3 basic_short 0 1 20 0
## 4 basic_steep 0.25 1 20 0
## 5 block_med 0 1 30 0
## 6 boomerang_left 0 2.5 30 0
## 7 boomerang_left 0.25 1 20 0
## 8 boomerang_middle 0 1 30 0
## 9 contain_corner 0.25 1 20 0
## 10 tunnel_narrow -0.25 2.5 30 0
## # ℹ 158 more rows
## number of attempts for trials
data %>%
count(levelID) %>%
arrange(n)
## # A tibble: 14 × 2
## levelID n
## <chr> <int>
## 1 basic_short 36
## 2 basic_drop 58
## 3 basic_steep 68
## 4 tunnel_narrow 83
## 5 tunnel_wide 84
## 6 contain_corner 87
## 7 basic_far 91
## 8 diagonal_descent 97
## 9 block_med 112
## 10 boomerang_left 112
## 11 boomerang_middle 120
## 12 basic_flat 140
## 13 block_long 142
## 14 diagonal_ascent 249
data %>%
count(levelID) %>%
ggplot(aes(x=reorder(levelID, n), y=n)) +
geom_bar(stat="identity") +
scale_x_discrete("level ID") +
coord_flip() +
theme_bw()
## of attempts for conditions
data %>%
count(gravX)
## # A tibble: 3 × 2
## gravX n
## <dbl> <int>
## 1 -0.25 603
## 2 0 458
## 3 0.25 418
data %>%
count(gravX) %>%
mutate(gravX = as.factor(gravX)) %>%
ggplot(aes(x=gravX, y=n, fill=gravX)) +
geom_bar(stat="identity", colour="black", show.legend=FALSE) +
geom_text(aes(label = n), position = position_dodge(0.9), vjust = -0.2) +
scale_x_discrete("Wind") +
scale_y_continuous("Number of Attempts") +
theme_bw()
## number of attempts for trials/conditions
data %>%
count(levelID) %>%
ggplot(aes(x=reorder(levelID, n), y=n)) +
geom_bar(stat="identity") +
scale_x_discrete("level ID") +
coord_flip() +
theme_bw()
## breakdown of outcome for each participant
data %>%
count(subjID, runOutcome)
## # A tibble: 81 × 3
## subjID runOutcome n
## <chr> <chr> <int>
## 1 0F07CDB90B goal 18
## 2 0F07CDB90B outofbound 5
## 3 0F07CDB90B stationary 13
## 4 1304BAAAAF goal 13
## 5 1304BAAAAF outofbound 6
## 6 1304BAAAAF stationary 34
## 7 1501C5CE8B goal 12
## 8 1501C5CE8B outofbound 20
## 9 1501C5CE8B stationary 32
## 10 1A8CD277EE goal 17
## # ℹ 71 more rows
ggplot(data, aes(x=runOutcome)) +
geom_bar(stat="count") +
facet_wrap(~subjID) +
theme_bw() +
theme(axis.text.x = element_text(angle=90, vjust=0, hjust=1))
## proportion of success for each participant
data %>%
count(subjID, runOutcome) %>%
filter(runOutcome == "goal") %>%
mutate(propsuccess = n/20) %>%
ggplot(aes(x = reorder(subjID, -propsuccess), y = propsuccess)) +
geom_bar(stat="identity") +
scale_x_discrete("subject ID") +
scale_y_continuous(limits=c(0,1), breaks=seq(0,1,0.2), expand=c(0,0)) +
coord_flip() +
theme_bw()
ggsave("fig/subjSuccess.png", width=3, height=6)
data %>%
mutate(outcome = ifelse(runOutcome == "goal", "success", "fail")) %>%
count(gravX, outcome) %>%
mutate(gravX = as.factor(gravX)) %>%
ggplot(aes(x=gravX, y=n, fill=outcome)) +
geom_bar(stat="identity", colour="black") +
scale_x_discrete("Wind") +
scale_y_continuous("Number of Attempts") +
scale_fill_manual(values=c("red","forestgreen")) +
theme_bw()
ggsave("fig/attByGravX.png", width=7, height=3)
data %>%
mutate(outcome = ifelse(runOutcome == "goal", "success", "fail")) %>%
count(gravY, outcome) %>%
mutate(gravY = as.factor(gravY)) %>%
ggplot(aes(x=gravY, y=n, fill=outcome)) +
geom_bar(stat="identity", colour="blue") +
scale_x_discrete("Planet") +
scale_y_continuous("Number of Attempts") +
scale_fill_manual(values=c("red","forestgreen")) +
theme_bw()
ggsave("fig/attByGravY.png", width=7, height=3)
data %>%
mutate(outcome = ifelse(runOutcome == "goal", "success", "fail")) %>%
count(radius, outcome) %>%
mutate(radius = as.factor(radius)) %>%
ggplot(aes(x=radius, y=n, fill=outcome)) +
geom_bar(stat="identity", colour="orange") +
scale_x_discrete("Marble Size") +
scale_y_continuous("Number of Attempts") +
scale_fill_manual(values=c("red","forestgreen")) +
theme_bw()
ggsave("fig/attBySize.png", width=7, height=3)
data %>%
mutate(outcome = ifelse(runOutcome == "goal", "success", "fail")) %>%
count(levelID, outcome) %>%
group_by(levelID) %>%
mutate(sum = sum(n)) %>%
ggplot(aes(x=reorder(levelID, sum), y=n, fill=outcome)) +
geom_bar(stat="identity", colour="gray") +
scale_x_discrete("Trial") +
scale_y_continuous("Number of Attempts") +
scale_fill_manual(values=c("red","forestgreen")) +
coord_flip() +
theme_bw()
ggsave("fig/attByTrial.png", width=7, height=7)
data %>%
mutate(outcome = ifelse(runOutcome == "goal", "success", "fail")) %>%
count(gravX, levelID, outcome) %>%
group_by(gravX, levelID) %>%
mutate(sum = sum(n),
gravX = paste("wind =", gravX)) %>%
ggplot(aes(x=reorder(levelID, sum), y=n, fill=outcome)) +
geom_bar(stat="identity", colour="gray") +
scale_x_discrete("Trial") +
scale_y_continuous("Number of Attempts", limits=c(0,110), breaks=seq(0,110, 25)) +
scale_fill_manual(values=c("red","forestgreen")) +
coord_flip() +
facet_wrap(~gravX) +
theme_bw()
ggsave("fig/attByTrialGravX.png", width=8, height=4)
data %>%
filter(levelID %in% c("diagonal_ascent", "basic_flat", "block_long", "boomerang_middle")) %>%
mutate(outcome = ifelse(runOutcome == "goal", "success", "fail")) %>%
count(gravY, radius, levelID, outcome) %>%
group_by(gravY, radius, levelID) %>%
mutate(sum = sum(n)) %>%
ggplot(aes(x=reorder(levelID, sum), y=n, fill=outcome)) +
geom_bar(stat="identity", colour="gray") +
scale_x_discrete("Trial") +
scale_y_continuous("Number of Attempts", limits=c(0,110), breaks=seq(0,110, 25)) +
scale_fill_manual(values=c("red","forestgreen")) +
coord_flip() +
facet_grid(gravY~radius) +
theme_bw()
data %>%
filter(gravY == 2.5 & radius == 20) %>%
mutate(outcome = ifelse(runOutcome == "goal", "success", "fail")) %>%
count(gravX, levelID, outcome) %>%
group_by(gravX, levelID) %>%
mutate(sum = sum(n),
gravX = paste("wind =", gravX)) %>%
ggplot(aes(x=reorder(levelID, sum), y=n, fill=outcome)) +
geom_bar(stat="identity", colour="gray") +
scale_x_discrete("Trial") +
scale_y_continuous("Number of Attempts", limits=c(0,110), breaks=seq(0,110, 25)) +
scale_fill_manual(values=c("red","forestgreen")) +
coord_flip() +
facet_wrap(~gravX) +
theme_bw()
maxAttempts <- data %>%
filter(numAttempts == 0) %>%
count(levelID, gravX) %>%
rename(maxAttempts = n)
# Number of Attempts
data %>%
count(levelID, gravX, numAttempts) %>%
complete(levelID, gravX, numAttempts, fill=list(n=0)) %>%
mutate(numAttempts = as.factor(numAttempts),
gravX = paste("wind =", gravX)) %>%
ungroup() %>%
group_by(levelID, gravX) %>%
mutate(sum = sum(n)) %>%
ggplot(aes(x = reorder(levelID, sum), y=n, fill=numAttempts)) +
geom_bar(stat="identity", position=position_dodge2(preserve = "single", reverse = TRUE)) +
scale_x_discrete("Trial") +
facet_wrap(~gravX) +
coord_flip() +
theme_bw()
ggsave("fig/survival.png", width=8, height=4)
# Proportion of Success over attempts
data %>%
mutate(success = ifelse(runOutcome == "goal", "success", "fail")) %>%
count(levelID, gravX, numAttempts, success) %>%
complete(levelID, gravX, numAttempts, success, fill=list(n=0)) %>%
filter(success == "success") %>%
left_join(maxAttempts, by=c("levelID","gravX")) %>%
mutate(gravX = paste("wind =", gravX)) %>%
group_by(levelID, gravX) %>%
mutate(cumsum = cumsum(n),
propSuccess = cumsum/maxAttempts,
numAttempts = numAttempts + 1) %>%
ggplot(aes(x = numAttempts, y=propSuccess)) +
geom_line(stat="identity", colour="blue", size=1.5) +
scale_x_continuous("Attempts") +
scale_y_continuous("Proportion of Success", limits=c(0,1), expand=c(0,0)) +
facet_grid(gravX~levelID) +
theme_bw()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
ggsave("fig/learning.png", width=12, height=4)
# proportion of successful attempts
data %>%
mutate(success = ifelse(runOutcome == "goal", "success", "fail"),
numSucc = as.numeric(success == "success")) %>%
ggplot(aes(x=numTrial, y=numSucc)) +
geom_point(stat="summary") +
geom_errorbar(stat="summary") +
geom_smooth() +
theme_bw()
## No summary function supplied, defaulting to `mean_se()`
## No summary function supplied, defaulting to `mean_se()`
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
# proportion successful trials
trialSuccess <- data %>%
group_by(subjID, numTrial, levelID, gravX, gravY, radius) %>%
summarise(success = ifelse("goal" %in% runOutcome, "success", "fail")) %>%
mutate(numSucc = as.numeric(success=="success"))
## `summarise()` has grouped output by 'subjID', 'numTrial', 'levelID', 'gravX',
## 'gravY'. You can override using the `.groups` argument.
trialSuccess %>%
ggplot(aes(x=numTrial, y=numSucc)) +
geom_point(stat="summary") +
geom_errorbar(stat="summary") +
geom_smooth() +
scale_x_continuous("Trial Number") +
scale_y_continuous("Proportion of Success") +
theme_bw()
## No summary function supplied, defaulting to `mean_se()`
## No summary function supplied, defaulting to `mean_se()`
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
ggsave("fig/learningTrials.png", width=7, height=4)
## No summary function supplied, defaulting to `mean_se()`
## No summary function supplied, defaulting to `mean_se()`
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
# mean of each action per attempt
strokedat %>%
group_by(subjID, numtrial, numattempt, action) %>%
count() %>%
group_by(action) %>%
summarise(mean = mean(n))
## # A tibble: 3 × 2
## action mean
## <chr> <dbl>
## 1 add 2.00
## 2 clear 2.17
## 3 undo 1.57
# mean of all actions per attempt
strokedat %>%
group_by(subjID, numtrial, numattempt) %>%
count() %>%
ungroup() %>%
summarise(mean = mean(n))
## # A tibble: 1 × 1
## mean
## <dbl>
## 1 3.13
strokedat %>%
group_by(subjID, numtrial, numattempt, action) %>%
count() %>%
ggplot(aes(x=numattempt, y=n, fill=action)) +
geom_bar(stat = "summary", position=position_dodge()) +
geom_errorbar(stat = "summary", position=position_dodge()) +
scale_x_continuous("attempt number") +
scale_y_continuous("number of action") +
theme_bw()
## No summary function supplied, defaulting to `mean_se()`
## No summary function supplied, defaulting to `mean_se()`
ggsave("fig/strokebyattempt.png", width=7, height=5)
## No summary function supplied, defaulting to `mean_se()`
## No summary function supplied, defaulting to `mean_se()`
strokedat %>%
group_by(subjID, numtrial, numattempt, action) %>%
count() %>%
ggplot(aes(x=numtrial, y=n, fill=action)) +
geom_bar(stat = "summary", position=position_dodge()) +
geom_errorbar(stat = "summary", position=position_dodge())
## No summary function supplied, defaulting to `mean_se()`
## No summary function supplied, defaulting to `mean_se()`
data %>%
mutate(logDrawTime = log(drawTime)) %>%
ggplot(aes(x=numTrial, y=logDrawTime)) +
geom_point()
ggsave("fig/drawtime.png", width=7, height=3)
data %>%
mutate(logRunTime = log(runTime)) %>%
ggplot(aes(x=numTrial, y=logRunTime)) +
geom_point()
ggsave("fig/runtime.png", width=7, height=3)
Individual participants’ time to trial success
data %>%
mutate(logDrawTime = log(drawTime)) %>%
ggplot(aes(x=numTrial, y=logDrawTime, colour=subjID)) +
geom_smooth(se=F)
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
data %>%
mutate(logDrawTime = log(drawTime)) %>%
ggplot(aes(x=numTrial, y=runTime, colour=subjID)) +
geom_smooth(se=F)
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
data %>%
count(subjID, numTrial) %>%
ggplot(aes(x=numTrial, y=n, colour=subjID)) +
geom_smooth(se=F)
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
IQR = quantile(data$drawTime, .75) - quantile(data$drawTime, .25)
lowerbound = quantile(data$drawTime, .25) - 1.5*IQR
upperbound = quantile(data$drawTime, .75) + 1.5*IQR
data %>%
filter(drawTime < upperbound) %>%
ggplot(aes(x=numTrial, y=drawTime)) +
geom_smooth() +
scale_y_continuous("drawing time")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
data %>%
count(subjID, numTrial) %>%
ggplot(aes(x=numTrial, y=n)) +
geom_smooth() +
scale_y_continuous("number of attempts")
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
# total trial time %>%
data %>%
group_by(subjID, numTrial) %>%
summarise(totalDrawTime = sum(drawTime),
totalRunTime = sum(runTime)) %>%
mutate(totalTime = totalDrawTime + totalRunTime) %>%
ggplot(aes(x=numTrial, y=totalRunTime)) +
geom_smooth()
## `summarise()` has grouped output by 'subjID'. You can override using the
## `.groups` argument.
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
parseJSON <- function(col) {
#converts ' to " except when surrounded by alphabetical letters, like "you've"
col <- str_remove_all(col, "\\[")
col <- str_remove_all(col, "\\]")
col <- str_replace_all(col, "(?<![a-zA-Z])'(.*?)'(?![a-zA-Z])", "\"\\1\"")
col <- lapply(col, fromJSON)
return(col)
}
data %>%
mutate(drawnLines = across(c("drawnLines"), parseJSONCol))
## # A tibble: 1,479 × 26
## subjID starttime useragent exptPart numTrial levelIndex levelID
## <chr> <dbl> <chr> <chr> <dbl> <dbl> <chr>
## 1 1DF28D04D4 1703865018453 Mozilla/5.0 (W… test 0 0 basic_…
## 2 1DF28D04D4 1703865018453 Mozilla/5.0 (W… test 0 0 basic_…
## 3 1DF28D04D4 1703865018453 Mozilla/5.0 (W… test 0 0 basic_…
## 4 1DF28D04D4 1703865018453 Mozilla/5.0 (W… test 1 13 boomer…
## 5 1DF28D04D4 1703865018453 Mozilla/5.0 (W… test 1 13 boomer…
## 6 1DF28D04D4 1703865018453 Mozilla/5.0 (W… test 1 13 boomer…
## 7 1DF28D04D4 1703865018453 Mozilla/5.0 (W… test 1 13 boomer…
## 8 1DF28D04D4 1703865018453 Mozilla/5.0 (W… test 1 13 boomer…
## 9 1DF28D04D4 1703865018453 Mozilla/5.0 (W… test 2 9 diagon…
## 10 1DF28D04D4 1703865018453 Mozilla/5.0 (W… test 2 9 diagon…
## # ℹ 1,469 more rows
## # ℹ 19 more variables: marbleStartLoc <chr>, cupLoc <chr>, blockLoc <chr>,
## # gravX <dbl>, gravY <dbl>, mass <dbl>, radius <dbl>, numAttempts <dbl>,
## # maxAttempt <dbl>, marbleEndLoc <chr>, marbleCoords <chr>,
## # marbleEndDist <dbl>, marbleMinDist <dbl>, runOutcome <chr>,
## # drawnLines <tibble[,1]>, drawnPhysObj <chr>, trialStartTime <dbl>,
## # drawTime <dbl>, runTime <dbl>